using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Visuals;
using FilteredStatistics.Controller;

namespace FilteredStatistics.View
{
    public partial class SelectColumnsForm : Form
    {
        public SelectColumnsForm(TreeListColumnManager columnManager)
        {
            InitializeComponent();

            this.Text = PluginView.GetLocalizedString("ListSettingsText");

            MainPanel.ThemeChanged(PluginMain.GetApplication().VisualTheme);
            MainPanel.BackColor = PluginMain.GetApplication().VisualTheme.Control;

            AvailableColumnLabel.Text = PluginView.GetLocalizedString("AvailableText");
            SelectedColumnLabel.Text = PluginView.GetLocalizedString("ColumnsInListText");
            AvailableColumnsList.Format += new ListControlConvertEventHandler(ColumnsList_Format);
            DisplayedColumnsList.Format += new ListControlConvertEventHandler(ColumnsList_Format);
            AddColumnButton.LeftImage = CommonResources.Images.DocumentAdd16;
            AddColumnButton.Text = PluginView.GetLocalizedString("AddColumnText");
            MoveUpButton.LeftImage = CommonResources.Images.MoveUp16;
            MoveDownButton.LeftImage = CommonResources.Images.MoveDown16;
            RemoveColumnButton.LeftImage = CommonResources.Images.Delete16;
            RemoveColumnButton.Text = CommonResources.Text.ActionRemove;
            FixedColumnLabel.Text = PluginView.GetLocalizedString("FixedColumnText");
            FixedColumnComboBox.Format += new ListControlConvertEventHandler(ColumnsList_Format);

            OKButton.Text = CommonResources.Text.ActionOk;
            Cancel_Button.Text = CommonResources.Text.ActionCancel;

            // Resize buttons for text, autosize doesn't work
            Graphics tempGraphics = this.CreateGraphics();
            AddColumnButton.Size = tempGraphics.MeasureString(AddColumnButton.Text, AddColumnButton.Font).ToSize() + new Size(32, 0); // Extra space for the image
            RemoveColumnButton.Size = tempGraphics.MeasureString(RemoveColumnButton.Text, RemoveColumnButton.Font).ToSize() + new Size(32, 0); // Extra space for the image
            tempGraphics.Dispose();

            foreach (TreeListColumnInfo columnInfo in columnManager.VisibleColumns)
            {
                m_VisibleColumns.Add(columnInfo.Clone());
            }
            foreach (TreeListColumnInfo columnInfo in columnManager.HiddenColumns)
            {
                m_HiddenColumns.Add(columnInfo.Clone());
            }

            if (columnManager.FixedColumnCount > 0)
            {
                m_FixedColumn = m_VisibleColumns[columnManager.FixedColumnCount - 1];
            }

            RefreshColumnsList();
        }

        void ColumnsList_Format(object sender, ListControlConvertEventArgs e)
        {
            TreeListColumnInfo columnInfo = e.ListItem as TreeListColumnInfo;

            if (columnInfo != null)
            {
                e.Value = columnInfo.HeaderText;
            }
            else if (sender == FixedColumnComboBox)
            {
                // "None" special case for fixed column
                e.Value = CommonResources.Text.LabelNone;
            }
        }

        private void OKButton_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.OK;
            Close();
        }

        private void Cancel_Button_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }

        private void AvailableColumnsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (AvailableColumnsList.SelectedItem != null)
            {
                DisplayedColumnsList.SelectedItems.Clear();

                AddColumnButton.Enabled = true;
                MoveUpButton.Enabled = false;
                MoveDownButton.Enabled = false;
                RemoveColumnButton.Enabled = false;
            }
        }

        private void AvailableColumnsList_DoubleClick(object sender, EventArgs e)
        {
            AddSelectedAvailableColumn();
        }

        private void DisplayedColumnsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (DisplayedColumnsList.SelectedItem != null)
            {
                AvailableColumnsList.SelectedItems.Clear();

                AddColumnButton.Enabled = false;
                MoveUpButton.Enabled = DisplayedColumnsList.SelectedIndex != 0;
                MoveDownButton.Enabled = DisplayedColumnsList.SelectedIndex != (DisplayedColumnsList.Items.Count - 1);
                RemoveColumnButton.Enabled = true;
            }
        }

        private void DisplayedColumnsList_DoubleClick(object sender, EventArgs e)
        {
            RemoveSelectedDisplayedColumn();
        }

        private void AddColumnButton_Click(object sender, EventArgs e)
        {
            AddSelectedAvailableColumn();
        }

        private void RemoveColumnButton_Click(object sender, EventArgs e)
        {
            RemoveSelectedDisplayedColumn();
        }

        private void MoveUpButton_Click(object sender, EventArgs e)
        {
            if(DisplayedColumnsList.SelectedItem != null)
            {
                TreeListColumnInfo selection = (TreeListColumnInfo)DisplayedColumnsList.SelectedItem;
                int index = m_VisibleColumns.IndexOf(selection) - 1;

                if (index >= 0)
                {
                    m_VisibleColumns.Reverse(index, 2);
                    RefreshColumnsList();
                    DisplayedColumnsList.SelectedItem = selection;
                }
            }
        }

        private void MoveDownButton_Click(object sender, EventArgs e)
        {
            if (DisplayedColumnsList.SelectedItem != null)
            {
                TreeListColumnInfo selection = (TreeListColumnInfo)DisplayedColumnsList.SelectedItem;
                int index = m_VisibleColumns.IndexOf(selection);

                if (index >= 0)
                {
                    m_VisibleColumns.Reverse(index, 2);
                    RefreshColumnsList();
                    DisplayedColumnsList.SelectedItem = selection;
                }
            }
        }

        private void FixedColumnComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            int newSelectedIndex = FixedColumnComboBox.SelectedIndex - 1;

            if (newSelectedIndex != -1)
            {
                m_FixedColumn = m_VisibleColumns[newSelectedIndex];
            }
            else
            {
                m_FixedColumn = null;
            }
        }

        private void RefreshColumnsList()
        {
            SortedList<String, TreeListColumnInfo> availableColumns = new SortedList<string,TreeListColumnInfo>();

            DisplayedColumnsList.Items.Clear();
            AvailableColumnsList.Items.Clear();
            FixedColumnComboBox.Items.Clear();

            // Add "None" item
            FixedColumnComboBox.Items.Add(CommonResources.Text.LabelNone);

            foreach (TreeListColumnInfo columnInfo in m_VisibleColumns)
            {
                DisplayedColumnsList.Items.Add(columnInfo);
                FixedColumnComboBox.Items.Add(columnInfo);
            }

            // we use a temp list to sort alphabetically
            foreach (TreeListColumnInfo columnInfo in m_HiddenColumns)
            {
                availableColumns.Add(columnInfo.HeaderText, columnInfo);
            }

            foreach (KeyValuePair<String, TreeListColumnInfo> columnInfo in availableColumns)
            {
                AvailableColumnsList.Items.Add(columnInfo.Value);
            }

            if (m_FixedColumn == null)
            {
                FixedColumnComboBox.SelectedIndex = 0;
            }
            else
            {
                FixedColumnComboBox.SelectedItem = m_FixedColumn;
            }
        }

        private void AddSelectedAvailableColumn()
        {
            if (AvailableColumnsList.SelectedItem != null)
            {
                TreeListColumnInfo columnInfo = (TreeListColumnInfo)AvailableColumnsList.SelectedItem;

                columnInfo.IsVisible = true;
                m_HiddenColumns.Remove(columnInfo);
                m_VisibleColumns.Add(columnInfo);

                RefreshColumnsList();

                DisplayedColumnsList.SelectedItem = columnInfo;
            }
        }

        private void RemoveSelectedDisplayedColumn()
        {
            if (DisplayedColumnsList.SelectedItem != null)
            {
                TreeListColumnInfo columnInfo = (TreeListColumnInfo)DisplayedColumnsList.SelectedItem;

                columnInfo.IsVisible = false;
                m_VisibleColumns.Remove(columnInfo);
                m_HiddenColumns.Add(columnInfo);

                if (m_FixedColumn != null && columnInfo == m_FixedColumn)
                {
                    m_FixedColumn = null;
                }

                RefreshColumnsList();

                AvailableColumnsList.SelectedItem = columnInfo;
            }
        }

        public List<TreeListColumnInfo> VisibleColumns
        {
            get { return m_VisibleColumns; }
        }

        public List<TreeListColumnInfo> HiddenColumns
        {
            get { return m_HiddenColumns; }
        }

        public int FixedColumnCount
        {
            get
            {
                if (m_FixedColumn == null)
                {
                    return 0;
                }

                return m_VisibleColumns.IndexOf(m_FixedColumn) + 1;
            }
        }

        private List<TreeListColumnInfo> m_VisibleColumns = new List<TreeListColumnInfo>();
        private List<TreeListColumnInfo> m_HiddenColumns = new List<TreeListColumnInfo>();
        private TreeListColumnInfo m_FixedColumn = null;
    }
}